<template>
  <ContentWrap>
    <el-container>
      <el-aside width="200px">
        <el-input v-model="filterText" :placeholder="t('dbms.createTable.search')" />
        <el-scrollbar class="scrollbar">
          <div class="scrollbar-flex-content">
            <el-tree
              ref="treeRef"
              :data="treeData"
              node-key="code"
              :props="treeProps"
              draggable
              :allow-drop="allowDrop"
              :allow-drag="allowDrag"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              @node-click="selectNode"
              @node-drop="handleDrop"
            >
              <template #default="{ node, data }">
                <div class="tree-item">
                  <template v-if="data.docType == 0">
                    <Icon
                      v-if="node.expanded"
                      icon="material-symbols:folder-open-rounded"
                      color="#DEB887"
                      hoverColor="#DEB887"
                    />
                    <Icon
                      v-else
                      icon="material-symbols:folder-rounded"
                      color="#DEB887"
                      hoverColor="#DEB887"
                    />
                  </template>
                  <template v-else>
                    <Icon icon="ph:file-html" color="#008000" hoverColor="#008000" />
                  </template>
                  <el-dropdown trigger="contextmenu">
                    <span>{{ node.label }}</span>
                    <template #dropdown>
                      <el-dropdown-item
                        ><el-dropdown-item v-if="data.docType == 0" @click="addShow(data)">{{
                          t('dbms.createTable.addBtn')
                        }}</el-dropdown-item>
                        <el-dropdown-item
                          v-if="data.code != 'root'"
                          @click="updateShow(node, data)"
                          >{{ t('dbms.createTable.updateBtn') }}</el-dropdown-item
                        >
                        <el-dropdown-item v-if="data.code != 'root'" @click="remove(node, data)">{{
                          t('dbms.createTable.delBtn')
                        }}</el-dropdown-item>
                      </el-dropdown-item>
                    </template>
                  </el-dropdown>
                </div>
              </template>
            </el-tree>
          </div>
        </el-scrollbar>
      </el-aside>
      <el-container>
        <el-header>
          <div style="text-align: left"
            >{{ editData.title }}<el-tag v-if="editData.code">{{ editData.code }}</el-tag>
          </div>
          <div style="text-align: right">
            <el-button-group>
              <el-button type="success">{{ t('dbms.createTable.genComponent') }}</el-button>
              <el-button v-if="editData.code" type="primary" @click="updateJsonData">{{
                t('dbms.createTable.saveConfig')
              }}</el-button>
            </el-button-group>
          </div>
        </el-header>
        <el-main>
          <el-scrollbar>
            <fc-designer ref="designer" />
          </el-scrollbar>
        </el-main>
      </el-container>
    </el-container>
  </ContentWrap>
  <Add ref="AddView" @callback="addCallBack" />

  <Update ref="UpdateView" @callback="updateCallBack" />
</template>
<script setup lang="ts">
import {
  deleteApi,
  getJsonDataApi,
  getTreeApi,
  moveApi,
  updateJsonDataApi
} from '@/api/dbms/createTable'
import { CreateTableTreeType, CreateTableType } from '@/api/dbms/createTable/types'
import { ContentWrap } from '@/components/ContentWrap'
import Icon from '@/components/Icon/src/Icon.vue'
import type Node from 'element-plus/es/components/tree/src/model/node'
import Add from './components/Add.vue'
import Update from './components/Update.vue'

import { onMounted, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox, ElTree } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { AllowDropType } from 'element-plus/es/components/tree/src/tree.type'

const { t } = useI18n()

//修改的数据
const editData = reactive<CreateTableType>({
  code: '',
  parentCode: '',
  title: '',
  submitUrl: '',
  docType: 0
})

const treeRef = ref<InstanceType<typeof ElTree>>()
//筛选
const filterText = ref('')
watch(filterText, (val) => {
  treeRef.value!.filter(val)
})
const filterNode = (value: string, data: CreateTableTreeType) => {
  if (!value) return true
  return data.title.includes(value)
}
//默认数据
const treeData = ref<CreateTableTreeType[]>([
  {
    code: 'root',
    parentCode: '',
    title: '目录',
    docType: 0,
    submitUrl: '',
    children: []
  }
])

const treeProps = {
  label: 'title'
}

const addDataCache = ref<CreateTableTreeType>()

const updateDataCache = ref<CreateTableTreeType>()
const updateNode = ref<Node>()
const addShow = (data: CreateTableTreeType) => {
  addDataCache.value = data
  AddView.value.show(data.code)
}
const updateShow = (node: Node, data: CreateTableTreeType) => {
  updateNode.value = node
  updateDataCache.value = data
  UpdateView.value.show(data)
}

const remove = (node: Node, data: CreateTableTreeType) => {
  ElMessageBox.confirm(t('dbms.createTable.delete'), t('common.delWarning'), {
    confirmButtonText: t('common.ok'),
    cancelButtonText: t('common.cancel'),
    type: 'warning'
  }).then(async () => {
    const rs = await deleteApi(data.code)
    if (rs.success) {
      const parent = node.parent
      const children: CreateTableTreeType[] = parent.data.children || parent.data
      const index = children.findIndex((d) => d.code === data.code)
      children.splice(index, 1)
    }
  })
}

const updateJsonData = async () => {
  const jsonData = designer.value.getJson()
  const option = designer.value.getOption()
  const rs = await updateJsonDataApi(editData.code, jsonData, JSON.stringify(option))
  if (rs.success) {
    ElMessage({
      message: t('common.saveSuccess'),
      type: 'success'
    })
  }
}

//拖拽
const allowDrop = (_draggingNode: Node, dropNode: Node, _type: AllowDropType) => {
  if (dropNode.data.docType === 1) {
    return false
  } else {
    return true
  }
}
const allowDrag = (draggingNode: Node) => {
  return draggingNode.data.code != 'root'
}
const handleDrop = async (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
  if (type == 'inner') {
    await moveApi(draggingNode.data.code, dropNode.data.code)
  } else {
    await moveApi(draggingNode.data.code, dropNode.parent.data.code)
  }
}
//加载树数据
const loadTree = async () => {
  const rs = await getTreeApi('root')
  treeData.value[0].children = rs.data
}

//挂载后加载树形数据
onMounted(() => {
  loadTree()
})

//构建设计器对象
const designer = ref<any>(null)
//新增页面
const AddView = ref<any>(null)

//添加文件或者文件夹后回调
const addCallBack = (data: CreateTableType) => {
  const node: CreateTableTreeType = {
    code: data.code,
    title: data.title,
    submitUrl: data.submitUrl,
    parentCode: data.parentCode,
    docType: data.docType
  }
  if (node.docType == 0) {
    node.children = []
  }
  addDataCache.value?.children?.push(node)
}

const updateCallBack = (data: CreateTableType) => {
  const node: CreateTableTreeType = {
    code: data.code,
    title: data.title,
    submitUrl: data.submitUrl,
    parentCode: data.parentCode,
    docType: data.docType
  }
  node.children = updateDataCache.value?.children
  updateDataCache.value = node
  const parent = updateNode.value?.parent
  const children: CreateTableTreeType[] = parent?.data.children || parent?.data
  const index = children.findIndex((d) => d.code === data.code)
  children.splice(index, 1)
  children.push(node)
}

const selectNode = async (data: CreateTableTreeType) => {
  if (data.docType == 1) {
    editData.code = data.code
    editData.title = data.title
    const rs = await getJsonDataApi(data.code)
    designer.value.setRule(JSON.parse(rs.data.jsonData))
    designer.value.setOption(JSON.parse(rs.data.formOption))
  }
}

//修改页面
const UpdateView = ref<any>(null)

onMounted(() => {
  designer.value.addMenu({
    title: '系统组件',
    name: 'system',
    list: []
  })
})
</script>
<style>
.dark ._fc-l-item {
  background: #141414;
  color: #f1f1f1;
}

.dark ._fc-m-drag {
  background-color: #141414 !important;
}

.dark ._fc_fetch {
  background-color: #141414 !important;
}

.dark ._fc-l-item:hover {
  background: #2e73ff;
  color: #fff;
}

.dark ._fc-r ._fc-r-tabs {
  border-bottom: 1px solid var(--el-border-color-light);
  display: flex;
  padding: 0;
}
</style>

<style scoped>
.scrollbar-flex-content {
  display: flex;
}
.tree-item {
  width: 150px;
  line-height: 16px;
  height: 16px;
  display: contents;
}
.tree-button {
  display: none;
}

.tree-item:hover .tree-button {
  display: inline;
}

.scrollbar {
  height: calc(100% - 32px);
}
</style>
